function getGetVar(url, varname){
	var GETDATA = new Array();
	var tmp = url.split("?");
	var sGet = tmp[1];
	if (sGet){
		sGet = sGet.substr(1);
		var sNVPairs = sGet.split("&");
		for (var i = 0; i < sNVPairs.length; i++){
			var sNV = sNVPairs[i].split("=");
			GETDATA[sNV[0]] = sNV[1];
		}
	}
	return GETDATA[varname];
}


function substr_replace (str, replace, start, length) {
    if (start < 0) { // start position in str
        start = start + str.length;
    }
    length = length !== undefined ? length : str.length;
    if (length < 0) {
        length = length + str.length - start;
    }
    return str.slice(0, start)+replace.substr(0, length)+replace.slice(length)+str.slice(start+length);
}
if( CtrlAjax == undefined ){
	var CtrlAjax = {
		
		silent_reload: false,
		tmp_selector: 1,
		beforeChangeStateCallbacks: {},
		loadCallbacks: {},
		globalLoadCallbacks: {},
		partialUpdate:{},
		
		
		addPartialUpdate: function(source, conf){
			if (typeof( source ) != 'string')
				source = CtrlAjax.getAjaxId(source);
			CtrlAjax.partialUpdate[source] = conf;
		},
		
		addLoadCallback:function( source, callback ){
			CtrlAjax.loadCallbacks[source] = callback;
		},
		
		addGlobalLoadCallback:function(  callback, selector ){
			if(selector == undefined || !selector){
				selector = CtrlAjax.tmp_selector;
				CtrlAjax.tmp_selector++;
			}
			CtrlAjax.globalLoadCallbacks[selector] =  callback;
		},
		
		addBeaforeChangeStateCallback:function( source, callback ){
			CtrlAjax.beforeChangeStateCallbacks[source] = callback;
		},
		
		
		addShadow:function(cont){
			if(cont.find(".ctrl-shadow").length == 0 ){
				var shadow = $('<div class="ctrl-shadow"></div>');
				var width = cont.width();
				if( width != null )
					shadow.width(width);
				var height = cont.height();
				if( height != null )
					shadow.height(height);
				
				shadow.hide();
				cont.append( shadow );
				shadow.fadeIn();
			}
		},
		
		getAjaxId: function(node){
			var ajax = $(node).parents(".ctrl-ajax").eq(0);
			if(!ajax || ajax.length == 0){
				return null;
			}
			var ajaxId = ajax.attr("class").replace("ctrl-ajax ", "").replace("ctrl-ajax-", "");
			
			return ajaxId;
		},
		
		parse:function(container){
			if(window.Page)
				Page.parseHtml(container);
			
			for(selector in CtrlAjax.loadCallbacks)
				CtrlAjax.loadCallbacks[selector]( container );
			
			for(selector in CtrlAjax.globalLoadCallbacks){
				try{
					CtrlAjax.globalLoadCallbacks[selector]( container, selector );
				}catch(ex){//todo
					
				}
			}			
		},
		
		applyEvents:function(selector,cont){
			if(window.Page)
				Page.parseHtml($(".ctrl-ajax-" +selector));
			if( CtrlAjax.loadCallbacks[selector] != undefined )
				CtrlAjax.loadCallbacks[selector]( cont );
			
			for(selector in CtrlAjax.globalLoadCallbacks){
				try{
					CtrlAjax.globalLoadCallbacks[selector]( cont, selector );
				}catch(ex){//todo
					
				}
			}
		},
		
		changeState:function( source, changeStateLink, getVars, callback){
			var cont = $(".ctrl-ajax-" +source);
			
			
			if (typeof( source ) != 'string')
				source = CtrlAjax.getAjaxId(source);
			
			if( CtrlAjax.beforeChangeStateCallbacks[source] != undefined )
				CtrlAjax.beforeChangeStateCallbacks[source]( cont );
			
			if(CtrlAjax.silent_reload === false)
				CtrlAjax.addShadow(cont);
			if(getVars){
				var query = $.query.load(changeStateLink);
				for(i in getVars)
					query = query.SET(i, getVars[i]);
				changeStateLink = query.toString();
			}
			
			$.get(changeStateLink,{}, function(response){
				
				if(CtrlAjax.partialUpdate[source] ){
					cont.find(".ctrl-shadow").remove();
					var res = $(response);
					for(i in CtrlAjax.partialUpdate[source]){
						var selector = CtrlAjax.partialUpdate[source][i];
						cont.find(selector).each(function(index,el){
							$(this).html(res.find(selector).eq(index).html());
						});
						if(cont.find(selector).length == 0){
							var loadedEl = res.find(selector);
							if(loadedEl.length != 0){
								var parentClass = loadedEl.parent().attr("class");
								cont.find("."+ parentClass).append(loadedEl);
							}
						}
					}
				
				}else{
					cont.html(response);
				}
				
				
				
				CtrlAjax.applyEvents(source,cont);
				
				
				if(callback)
					callback($(".ctrl-ajax-" +source));
				
			}, "text");
		},
		reload:function(source, callback){
			if (typeof( source ) != 'string')
				source = CtrlAjax.getAjaxId(source);
			
			var cont = $(".ctrl-ajax-" +source);
			var currState = cont.children(".ctrl-current-state", cont).val();
			if( currState == undefined )
				alert("Brak stanu obiektu" + ".ctrl-ajax-" +source);
			else
				CtrlAjax.changeState( source, currState, {}, callback );
		},
		
		changeStateVars:function(source, vars, getVars, callback){
			
			if (typeof( source ) != 'string')
				source = CtrlAjax.getAjaxId(source);
			
			var cont = $(".ctrl-ajax-" + source);
			var states = $(".ctrl-current-state", cont);
			var currState = states.eq(states.length-1).val();
			if(currState == undefined){
				//alert(cont.html());
				alert("Read controll state error ["+source+"], [" + ".ctrl-ajax-" + source+"]");
				return false;
			}
			
			var controlVar = getGetVar(currState, "ctrlstate" );
			if(controlVar == undefined) controlVar = "";
			var controlId = getGetVar(currState, "ctrl-ctrlGlobalId" );
			var state = CtrlAjax.unserialize(controlVar);
			if(state[controlId] == undefined){
				state[controlId] = new Array();
			}
			for(key in vars)
				state[controlId][key] = (vars[key]);
			
			
			var serialized = CtrlAjax.serialize(state);
			if(controlVar != "")
				var newState = currState.replace("ctrlstate="+controlVar, "ctrlstate="+serialized);
			else
				var newState = currState + "&ctrlstate="+serialized;
			
			CtrlAjax.changeState( source, newState, getVars, callback );
		},
		
		changeStateVar:function(source, varName, value, callback ){
			
			if (typeof( source ) != 'string')
				source = CtrlAjax.getAjaxId(source);
			
			var cont = $(".ctrl-ajax-" +source);
			var states = $(".ctrl-current-state", cont);
			var currState = states.eq(states.length-1).val();
			var controlVar = getGetVar(currState, "ctrlstate" );
			if(controlVar == undefined) controlVar = "";
			var controlId = getGetVar(currState, "ctrl-ctrlGlobalId" );
			var state = CtrlAjax.unserialize(controlVar);
			if(state[controlId] == undefined){
				state[controlId] = new Array();
			}
			state[controlId][varName] = (value);
			
			var serialized = CtrlAjax.serialize(state);
			var newState = currState.replace("ctrlstate="+controlVar, "ctrlstate="+serialized);
			
			CtrlAjax.changeState( source, newState, callback );
		},
		
		getStateVar:function(source, varName){
			if (typeof( source ) != 'string')
				source = CtrlAjax.getAjaxId(source);
			var cont = $(".ctrl-ajax-" +source);
			var currState = cont.children(".ctrl-current-state").val();
			var controlVar = getGetVar(currState, "ctrlstate" );
			var controlId = getGetVar(currState, "ctrl-ctrlGlobalId" );
			var state = CtrlAjax.unserialize(controlVar);
			
			if(!state[controlId])
				state[controlId] = new Array();
			return state[controlId][varName];
			
		},
		unserialize:function( string){
			var data = new Array();
			var main = string.split("||");
			for(var i=1;i<main.length;i+=2){
				var local = main[i+1].split("|");
				data[main[i]] = new Array();
				for( var j=0;j<local.length;j+=2){
					data[main[i]][local[j]] = local[j+1];
				} 			
			}
			return data;
		},
		
		serialize:function(data){
			var str = "";
			for( i in data ){
				str+="||"+i+"|";
				for( j in data[i] ){
					str+="|"+j+"|" + data[i][j];
				}
			}
			return str;
		},
		doAction:function(disable, model,action,key, data, callback, addData){
			CtrlAjax.addShadow($(disable));
			
			var sendData = {};
			for(i in data)
				sendData["data["+i+"]"] = data[i];
			
			if(addData){
				for(i in addData)
					sendData[i]= addData[i];
			}
			ArrowDataConnector.execute({
				url: 'index.php?arrowDataRequest=8&action='+action+'&key='+key+'&model='+ model,
				params: sendData,
				callback: function(response){
					
					if(response !== null) { 
						if(callback){ callback(response); } 
						else {  
							alert('obiekt powiązany w innym miejscu');   // komunikat do zmiany podpięcie Response readera
						}
					}
					$(".ctrl-shadow", disable).remove();
				},
				interactionCallback: function(interaction) {
					//ArrowInteraction._do(interaction);
					$(".ctrl-shadow", disable).remove();
				}
			});
			 
		},
		registerEvent:function(source, on, eventType ){
			alert("event1");
			
		},
		event:function(source, on, args){
			alert("event2");
		},
		
		runControllAction:function(source, name, data, callback){
			if (typeof( source ) != 'string')
				source = CtrlAjax.getAjaxId(source);
			var cont = $(".ctrl-ajax-" + source);
			var states = $(".ctrl-current-state", cont);
			var currState = states.eq(states.length-1).val().replace("arrowControllRequest", "arrowControllActionRequest");
			
			var query = $.query.load(currState);
			query = query.SET("ctrl-actionDelegate", name);
			CtrlAjax.addShadow(cont);
			
			$.post(query, data, function(response){
				cont.find(".ctrl-shadow").remove();
				if(callback)
					callback(response, cont);
				
			});
		}
		
	}
	
	function ctrlInitArrowCtrlAjax(context, selector){};
	
	
}